//
// You should NOT edit app.js directly
// because it's the compiled result
// edit app.src.js instead
// and compile to app.js with babel
//
// Note:
// The overall structure is:
// if ($body.hasClass(...))
//   class ... {}
// though some code inside classes are not so elegant
// but this structure should be followed
//
// Kelvin @ Xenyo
//
jQuery(function($) {
  'use strict'
  // cache global DOM
  const $html = $('html'),
    $body = $('body'),
    $win = $(window),
    $doc = $(document),
    $main = $('#main'),
    $content = $('#content'),
    $footer = $('.region-bottom')
  let nid = $('article.app').data('nid')
  if (!window.location.origin) {
    window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
  }
  // interface
  class Base {
    constructor(_nid) {
      this.url = ''
      this.title = ''
      this.el = null
      this.nid = _nid || nid
      this.description = $('meta[property="og:description"]').attr('content') || ''
    }
    socialShare() {
      let $amount = this.el.find('.article-share-amount:eq(0) strong')
      let $share = this.el.find('.article-share-action:eq(0)')
      let setting = 'toolbar=no, location=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=500, height=400'
      // for pinterest, need bigger popup
      let setting2 = 'toolbar=no, location=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=800, height=680'
      // slide In/Out the social share btns
      $share.find('.article-share-toggle').on('click', function(e) {
        e.preventDefault()
        $share.toggleClass('expand')
      })
      $share.find('.article-share-open').on('click', function(e) {
        e.preventDefault()
        $share.addClass('expand')
      })
      $share.find('.article-share-close').on('click', function(e) {
        e.preventDefault()
        $share.removeClass('expand')
      })
      // set Real share links
      let currentUrl = encodeURIComponent(this.url)
      let title = encodeURIComponent(this.title)
      $share.find('.icon-facebook').on('click', function(e) {
        e.preventDefault()
        window.open('http://www.facebook.com/sharer.php?u=' + currentUrl + '&t=' + title, 'targetWindow', setting)
      })
      $share.find('.icon-sina').on('click', function(e) {
        e.preventDefault()
        window.open("http://service.weibo.com/share/share.php?url=" + currentUrl + "&title=" + title, 'targetWindow', setting)
      })
      // let pinLink = "http://pinterest.com/pin/create/button/?url=" + currentUrl + "&media=&description=" + title
      // $share.find('.icon-pinterest').attr('href', pinLink)
      $share.find('.icon-pinterest').on('click', function(e) {
        e.preventDefault()
        let pinLink = "http://pinterest.com/pin/create/button/?url=" + currentUrl + "&media=&description=" + title
        window.open(pinLink, 'targetWindow', setting2)
      })
      // mail button
      let mailTitle = title.trim()
      let mailBody = this.url + '%0D%0A'
      if (this.description.length > 20) {
        mailBody += this.description.substr(0, 20) + '...'
      } else {
        mailBody += this.description
      }
      let mailLink = `mailto:?subject=${mailTitle}&body=${mailBody}`
      $share.find('.icon-mail').attr('href', mailLink)
      // update the share count
      $share.find('.article-share-icon:not(.icon-mail)').on('click', (function() {
        $.post('/api/v1/post/social/share/count', {
          article_id: this.nid
        }, function(res) {
          // console.log('checked share count:', res)
          if (res.success) {
            $amount.text(res.data.count)
          }
        }).fail(function(res) {
          console.warn('checked share count:', res)
        })
      }).bind(this))
    }
    initFB() {
      if (typeof FB !== 'undefined') {
        FB.XFBML.parse()
      }
    }
  }
  // styling article & styling item
  if ($body.hasClass('node-type-xenyo-sc-styling-article') || $body.hasClass('node-type-xenyo-sc-styling-item')) {
    class detailPage extends Base {
      constructor() {
        super()
        this.url = location.href
        this.el = $('#content > article.app')
        this.title = $('title:eq(0)').text()
        this.socialShare()
      }
    }
    new detailPage()
  }
  // styling article
  if ($body.hasClass('node-type-xenyo-sc-styling-article')) {
    let $wrapper = $('.img-wrapper'),
      $img = $wrapper.find('img'),
      imgW = $img.outerWidth(true)
    class imagePin extends Base {
      constructor() {
        super()
        this.pins = []
        let self = this
        image_pin_data.pins.forEach(function(v, k) {
          let instock = v.instock ? 'instock' : ''
          let html = `
                            <div class="pin">
                                <div class="pin-point">&nbsp</div>
                                <div class="pin-content">`
          if (v.buy) {
            html += `<a class="pin-icon ${instock}" href="${v.buy}" target="_blank"></a>`
          }
          if (v.url.length) {
            html += `<a class="pin-title" href="${v.url}">${v.brand}</a>`
          }
          html += `</div></div>`
          let $pin = $(html)
          self.pins.push($pin)
          $pin.appendTo($wrapper)
          $pin.css({
            'position': 'absolute',
            'left': v.x + '%',
            'top': v.y + '%'
          })
          // detect if overflow at the right side
          if (v.x > 50) {
            $pin.addClass('right')
          } else {
            $pin.addClass('left')
          }
        })
        this.bindEvents()
      }
      bindEvents() {
        let self = this
        $('.pin-toggle').on('click', function() {
          self.pins.forEach(function(v, k) {
            v.toggle()
          })
        })
      }
    }
    new imagePin()
  }
  // stylebook
  if ($body.hasClass('page-stylebook') && !$body.hasClass('page-stylebook-item')) {
    class Pin {
      constructor(el) {
        this.container = el
        this.img = el.find('.field-image')
        this.pin = null
        this.toggleBtn = null
        this.data = null
        // get the JSON data in hidden field
        let data = JSON.parse(Base64.decode(this.container.find('.item_data').attr('data')))
        if (data.hasOwnProperty('brand')) {
          this.data = data
          // Direction
          // 1:TL, 2:TR, 3:BL, 4:BR
          let direction
          switch (this.data.direction) {
            case '1':
              direction = 'direction-tl'
              break
            case '2':
              direction = 'direction-tr'
              break
            case '3':
              direction = 'direction-bl'
              break
            case '4':
              direction = 'direction-br'
              break
          }

          function dummyDirection(x, y) {
            if (x < 50 && y < 50) {
              return 1
            } else if (x >= 50 && y < 50) {
              return 2
            } else if (x < 50 && y >= 50) {
              return 3
            } else if (x >= 50 && y >= 50) {
              return 4
            }
          }
          // In stock
          let classBuy = this.data.buy ? '' : 'no-buy'
          let classInstock = this.data.instock ? 'instock' : ''
          // position
          let style = 'left:' + this.data.x + '% top:' + this.data.y + '%'
          let html = `
                        <div class="pin ${direction} ${classInstock} ${classBuy}" style="${style}" data-nid="${this.data.nid}">
                            <div class="pin-point"></div>
                            <div class="pin-body ">
                                <div class="pin-body-inner">
                                    <a class="pin-image" href="${this.data.url}">
                                        <img src="${this.data.thumbnail}" alt="">
                                    </a>
                                    <div class="pin-text">
                                        <div class="pin-name">${this.data.brand}</div>
                                        <div class="pin-price">${this.data.price}</div>
                                    </div>`
          if (this.data.buy) {
            html += `<a href="${this.data.buy}" class="pin-stock" target="_blank"></a>`
          }
          html += `
                                </div>
                            </div>
                        </div>`
          // create PIN html el
          this.pin = $(html)
          this.pin.appendTo(this.img)
          this.container.addClass('inited')
          this.toggleBtn = $('<div class="pin-toggle"></div>')
          this.toggleBtn.appendTo(this.img)
          this.toggleBtn.on('click', this.toggle.bind(this))
        }
      }
      toggle() {
        this.pin.toggle()
      }
    }

    function updatePins() {
      $('.view-lookbook .view-row').each(function(k, v) {
        if (!$(v).hasClass('inited')) {
          let p = new Pin($(v))
        }
      })
    }
    updatePins()
    $doc.ajaxComplete(function(event, xhr, settings) {
      updatePins()
    })
  }
  // stylebook & lookbook
  if ($body.hasClass('page-stylebook-item') || $body.hasClass('page-stylebook')) {
    class StyleAndLook {
      constructor() {
        this.initAccordion()
        // set the view count
        let $source = $('.result-count')
        let $dist = $('.section-head .view-count')
        if ($source.length && $dist.length) {
          $source.hide()
          $dist.text($source.text())
        }
      }
      initAccordion() {
        // sidebar filter > accordion
        $('.filter-accordion .filter-accordion-toggle').on('click', function(e) {
          let $this = $(this)
          let $child = $this.next()
          if ($this.toggleClass('active').hasClass('active')) {
            TweenLite.set($child, {
              height: 'auto'
            })
            TweenLite.from($child, 0.3, {
              height: 0,
              onComplete: function() {
                $child.css('overflow', 'visible')
              }
            })
          } else {
            $child.css('overflow', 'hidden')
            TweenLite.to($child, 0.3, {
              height: 0
            })
          }
        })
      }
    }
    new StyleAndLook()
  }
  // stylebook item
  if ($body.hasClass('node-type-xenyo-sc-styling-item')) {
    // slideshow
    class Slideshow {
      constructor() {
        this.amount = 15
        this.container = $("#slideshow")
        $.when(this.getJson()).then((json) => {
          this.data = json
          this.initHTML()
          this.initSlick()
        })
      }
      getJson() {
        let dfd = jQuery.Deferred()
        $.get(`/api/v1/style-items/images/${nid}`, (json) => {
          dfd.resolve(json)
        })
        return dfd.promise()
      }
      initHTML() {
        for (let i = 0; i < this.data.length; i++) {
          let img = this.data[i].main.image
          let imgalt = this.data[i].main.alt
          let thumb = this.data[i].thumbnail.image
          let thumbalt = this.data[i].thumbnail.alt
          this.container.append(`<div class="slide" data-thumb="${thumb}" data-thumbalt="${thumbalt}"><img data-lazy="${img}" alt="${imgalt}" /></div>`)
        }
      }
      initSlick() {
        this.container.slick({
          slidesToShow: 1,
          slidesToScroll: 1,
          arrows: true,
          dots: true,
          customPaging: function(slider, i) {
            let thumb = $(slider.$slides[i]).data('thumb')
            let thumbalt = $(slider.$slides[i]).data('thumbalt')
            return `<a class="yeah"><img src="${thumb}" alt="${thumbalt}"></a>`
          }
        })
      }
    }
    let slideshow = new Slideshow()
  }
  window.kv = "Kelvin's debugging."
  // article
  if ($body.hasClass('node-type-xenyo-sc-article') || $body.hasClass('node-type-msw') || $body.hasClass('node-type-gallery') || $body.hasClass('node-type-jtv')) {
    let $loading = $('#article-loading')
    class Gallery {
      constructor(_article) {
        this.article = _article
        this.api = '/jessica/api/restapi_views/gallery?display_id=embed_1&args='
        this.duration = 200
        this.cacheDom()
        this.getJson()
        this.updateNextArticle()
      }
      getJson() {
        $.ajax({
          method: 'GET',
          url: this.api + this.article.nid
        }).done((json) => {
          this.json = json
          this.createSlideshow()
          this.bindEvent()
        })
      }
      cacheDom() {
        this.$slideshow = this.article.el.find('.gallery-slideshow')
        this.$popup = this.article.el.find('.gallery-popup')
        this.$popupLast = this.article.el.find('.gallery-last-slide')
        this.$popupList = this.article.el.find('.gallery-popup-list')
        this.$popupBtn1 = this.article.el.find('.article-top .gallery-popup-btn')
        this.$popupBtn2 = this.article.el.find('.gallery-slideshow-wrapper .gallery-popup-btn')
      }
      updateNextArticle() {
        this.article.el.find('.gallery-suggestion > a:last').clone().appendTo(this.$popupLast.find('.gallery-last-slide-wrapper')).find('p').prepend('<span>Next Article</span><br/>')
      }
      // update article-top popupbtn text i.e. 1/4
      updateViewAll(currentIndex, total) {
        this.$popupBtn1.find('span').text(currentIndex + '/' + total)
      }
      createSlideshow() {
        TweenMax.to(this.$popupLast, 0, {
          left: '100%',
          display: 'block'
        })
        let sliderManager = new Hammer.Manager(this.$popupLast[0])
        let percent
        sliderManager.add(new Hammer.Pan({
          threshold: 0,
          pointers: 0
        }))
        sliderManager.on("pan", (e) => {
          percent = 100 * e.deltaX / 700
          TweenMax.to(this.$popupLast, 0, {
            left: percent + '%'
          })
          if (e.isFinal) {
            if (e.velocityX > 1) {
              TweenMax.to(this.$popupLast, .5, {
                left: '100%'
              })
            } else if (e.velocityX < -1) {
              TweenMax.to(this.$popupLast, .5, {
                left: 0
              })
            } else {
              if (percent <= -25) {
                TweenMax.to(this.$popupLast, .5, {
                  left: 0
                })
              } else if (percent >= 25) {
                TweenMax.to(this.$popupLast, .5, {
                  left: '100%'
                })
              } else {
                TweenMax.to(this.$popupLast, .5, {
                  left: 0
                })
              }
            }
          }
        })
        this.$popupBtn2.find('span').text(this.json.content.length)
        _.forEach(this.json.content, (v, k) => {
          let slideshowHtml = `
                                <div class="gallery-slide">
                                    <div class="gallery-slide-image">${v.field_image}</div>
                                    <div class="gallery-slide-content">
                                        <p>${v.field_body}</p>
                                    </div>
                                </div>`
          let popupHtml = `<div class="gallery-popup-image" data-index="${k}">${v.field_image}</div>`
          this.$slideshow.append(slideshowHtml)
          this.$popupList.append(popupHtml)
        })
        let slick
        this.$slideshow.on('init', (e, _slick) => {
          slick = _slick
          this.article.collapse()
          this.updateViewAll(slick.currentSlide + 1, slick.slideCount)
        })
        this.$slideshow.slick({
          slidesToShow: 1,
          adaptiveHeight: true,
          arrows: true,
          infinite: false
        })
        this.$slideshow.on('afterChange', (e, slick, currentSlide) => {
          this.updateViewAll(currentSlide + 1, slick.slideCount)
        })
        // show the dark overlay while hit the last slide
        this.$slideshow.on('edge', (e, slick, direction) => {
          if (direction === 'left') {
            TweenMax.to(this.$popupLast, .5, {
              left: 0
            })
          }
        })
      }
      popupToggle(fadeIn) {
        if (fadeIn) {
          this.$popup.stop().fadeIn(this.duration)
        } else {
          this.$popup.stop().fadeOut(this.duration)
        }
      }
      bindEvent() {
        this.$popup.on('click', (e) => {
          this.popupToggle(false)
        })
        this.$popupBtn1.add(this.$popupBtn2).on('click', (e) => {
          this.popupToggle(true)
        })
        this.$popupList.find('.gallery-popup-image').on('click', (e) => {
          let index = $(event.currentTarget).data('index')
          this.$slideshow.slick('slickGoTo', index)
        })
      }
    }
    class Article extends Base {
      constructor(url, perpetual) {
        super()
        this.url = url.substr(0, 4) === 'http' ? url : location.protocol + '//' + location.hostname + url
        this.title = ''
        this.index = 0
        this.inited = false
        this.left = null
        this.right = null
        this.el = null
        this.dimension = []
        this.script = []
        this.gaSent = false
        if ($body.hasClass('node-type-xenyo-sc-article')) {
          this.type = 'sc-article'
        } else if ($body.hasClass('node-type-msw')) {
          this.type = 'msw'
        } else if ($body.hasClass('node-type-gallery')) {
          this.type = 'gallery'
        } else if ($body.hasClass('node-type-jtv')) {
          this.type = 'jtv'
        }
      }
      init(isFirst) {
        this.isFirst = isFirst
        this.inited = true
        if (isFirst) {
          this.cacheDom()
          this.readmore()
          this.socialShare()
          if (this.type === 'gallery') {
            this.gallery = new Gallery(this)
          } else {
            this.collapse()
          }
        } else {
          this.getArticle().done((function(html) {
            this.cacheDom(html)
            this.insertArticle()
            this.readmore()
            this.socialShare()
            this.initFB()
            this.initSwiper()
            if (this.type === 'gallery') {
              this.gallery = new Gallery(this)
            } else {
              setTimeout(() => {
                this.collapse()
              }, 1000)
            }
          }).bind(this))
        }
      }
      getArticle() {
        let d = jQuery.Deferred()
        PubSub.publish('loadingStart')
        $.get(this.url, function(html) {
          d.resolve(html)
        })
        return d.promise()
      }
      cacheDom(html) {
        if (this.isFirst) {
          this.el = $('#content > article.app')
          this.title = $('title:eq(0)').text()
          let $dimension = $('.ga-dimension')
          // extract ga dimension
          if ($dimension.length && $dimension.is(['data-ga'])) {
            this.dimension = JSON.parse($('.ga-dimension').attr('data-ga'))
          } else {
            console.warn('ga-dimension not found.')
            this.dimension = []
          }
        } else {
          let self = this
          let dom = $(html)
          // extract page title
          dom.filter('title').each((k, v) => {
            self.title = $(v).text()
          })
          // extract ga dimension
          this.dimension = []
          let $domGa = dom.find('.ga-dimension')
          if ($domGa.length && $domGa.is(['data-ga'])) {
            this.dimension = JSON.parse($domGa.attr('data-ga'))
          }
          // extract script elements for google dfp ads
          dom.filter('script').each((k, v) => {
            if ($(v).hasClass('google-dfp-ads')) {
              let script = v.text || v.textContent || v.innerHTML || ''
              this.script.push(script)
            }
          })
          // grab og:description as body text
          this.description = dom.filter('meta[property="og:description"]').attr('content') || ''
          this.el = $(html).find('#content > article.app')
        }
        this.nid = this.el.data('nid')
        this.left = this.el.find('.section-left')
        this.right = this.el.find('.section-right')
      }
      sendGa() {
        // ga set referrer to previous article url (is history states)
        let prevIndex = History.getCurrentIndex() - 1
        if (prevIndex < 0) {
          prevIndex = 0
        }
        let prevUrl = History.getStateByIndex(prevIndex).url
        // ga('set', 'referrer', prevUrl)
        // ga set dimension
        _.forEach(this.dimension, (v, k) => {
          ga('set', 'dimension' + v.index, v.value)
        })
        ga('set', 'dimension8', Drupal.settings.ocga.ocID) || ''
        ga('set', 'dimension9', Drupal.settings.ocga.ocTitle) || ''
        ga('set', 'dimension10', Drupal.settings.ocga.ocURL) || ''
        ga('set', 'dimension11', Drupal.settings.ocga.ocAuthor) || ''
        ga('set', 'dimension12', this.index)
        ga('set', 'dimension13', prevUrl)
        // ga send pageview
        ga('send', 'pageview', {
          'page': this.url,
          'title': this.title
        })
        // ga run dfp script
        _.forEach(this.script, (v, k) => {
          $.globalEval(v)
        })
      }
      insertArticle() {
        this.el.insertAfter($content.find('article.app:last'))
        $win.resize()
        PubSub.publish('loadingEnd', {
          article: this
        })
      }
      collapse() {
        // if article is longer than sidebar
        // collapse it with "READ MORE" btn
        let leftH = this.left.outerHeight(true)
        let rightH = this.right.outerHeight(true)
        if (leftH > rightH && leftH > 900) {
          this.left.css({
            height: rightH > 800 ? rightH : 800,
          }).addClass('collapsed')
        }
      }
      readmore() {
        this.el.find('.article-readmore a').on('click', (e) => {
          e.preventDefault()
          let currentH = this.left.outerHeight(true)
          TweenLite.set(this.left, {
            height: 'auto'
          })
          TweenLite.from(this.left, .5, {
            height: currentH,
            ease: Power0.easeNone,
            onComplete: (function() {
              this.left.removeClass('collapsed')
            }).bind(this)
          })
        })
      }
      imageCaption() {
        this.el.find('.field-image').each(function(k, v) {
          let $img = $(v).find('img')
          let $caption = $(v).find('.article-image-caption')
          $caption.width($img.width())
        })
      }
      initSwiper() {
        this.el.find(".swiper.field-type-image").each(function() {
          var $this = $(this)
          var $container = $(this).find(".swiper-container")
          $container.swiper({
            watchActiveIndex: true,
            slidesPerView: 3,
            visibilityFullFit: true,
            calculateHeight: true,
            resizeReInit: true,
            onSwiperCreated: function(swiper) {
              // Add Next & Prev button
              // console.log($this)
              // console.log($container)
              if ($this.find(".swiper-slide").length >= 3) {
                $this.find(".slide-button.next").click(function() {
                  swiper.swipeNext()
                })
                $this.find(".slide-button.prev").click(function() {
                  swiper.swipePrev()
                })
              } else {
                $this.find(".swiper-control").remove()
              }
            }
          })
        })
      }
    }
    class Perpetual {
      constructor() {
        this.articles = []
        // init current article first
        let currentArticle = new Article(location.href)
        currentArticle.init(true)
        this.articles.push(currentArticle)
        this.getArticlesJson()
        this.setArticlesIndex()
        this.bindEvents()
      }
      getArticlesJson() {
        let drupalNids = Drupal.settings.article_nids || Drupal.settings.msw_nids || Drupal.settings.gallery_nids || []
        this.articles = this.articles.concat(_.map(drupalNids, function(v, k) {
          return new Article('/' + v)
        }))
      }
      setArticlesIndex() {
        this.articles = _.map(this.articles, (v, k) => {
          v.index = k
          return v
        })
      }
      bindEvents() {
        let self = this
        let winst = $win.scrollTop()
        let winH = $win.height()
        let triggerArea = winH * 2
        let currentIndex = 0
        let currentUrl = ''
        let oldIndex = currentIndex
        let loading = false

        function checkPushState() {
          // update pushstate while entering each article
          let offset = -120
          self.articles.forEach(function(v, k) {
            if (v.el && v.el.length && winst + offset > v.el.position().top && winst + offset < v.el.position().top + v.el.outerHeight(true)) {
              currentIndex = k
              return false
            }
          })
          if (oldIndex !== currentIndex) {
            oldIndex = currentIndex
            let art = self.articles[currentIndex]
            currentUrl = art.url
            History.pushState(null, art.title, currentUrl)
            // update page title
            document.title = art.title
            // console.log(art)
            // trigger GA update
            art.sendGa()
            /*
            // GA send (only one time)
            if (!art.gaSent) {
                ga('send', 'pageview', {
                    'page': art.url,
                    'title': art.title
                })
                self.articles[currentIndex].gaSent = true
            }
            */
            // show ONLY current article druapl admin tab
            self.articles.forEach(function(v, k) {
              if (v.inited && v.el) v.el.find('.tabs-primary').hide()
              art.el.find('.tabs-primary').show()
            })
          }
        }

        function checkHitBottom() {
          // check hit bottom & load new article
          if (winst + winH + triggerArea >= $footer.position().top) {
            if (!loading) {
              PubSub.publish('loadingStart')
              // check the next not-loaded article
              for (let i = 0; i < self.articles.length; i++) {
                let a = self.articles[i]
                if (!a.inited) {
                  a.init()
                  break
                }
              }
              // preload 2 next articles....
              // for (let i = 0 i < self.articles.length i++) {
              //     let a = self.articles[i]
              //     if (!a.inited) {
              //         a.init()
              //         break
              //     }
              // }
            }
          }
        }
        $win.on('load scroll', () => {
          winst = $win.scrollTop()
          winH = $win.height()
          // triggerArea = winH * 2
          triggerArea = winH * 1.3
          checkPushState()
          checkHitBottom()
        })
        PubSub.subscribe('loadingStart', function(msg, data) {
          loading = true
          $loading.show()
        })
        PubSub.subscribe('loadingEnd', function(msg, data) {
          $loading.hide()
          checkPushState()
          checkHitBottom()
          loading = false
        })
      }
    }
    // force init the app at the end of thread
    setTimeout(function() {
      $win.scrollTop(0, -1)
      new Perpetual()
    }, 0)
  }
  if ($body.hasClass('section-jessica-tv') || $body.hasClass('section-jtv') || $body.hasClass('section-jessica-channel') || $body.hasClass('node-type-jtv')) {
    class Jglobal {
      constructor() {
        this.initSidemenu()
        this.initSearch()
      }
      initSidemenu() {
        this.$sidemenuToggle = $('#sidemenu-toggle')
        this.$sidemenu = $('#sidemenu')
        this.$sidemenuToggle.on('click', (e) => {
          this.$sidemenuToggle.toggleClass('active')
          if (this.$sidemenuToggle.hasClass('active')) {
            // this.$sidemenu.show()
            TweenMax.set(this.$sidemenu, {
              height: 'auto'
            })
            TweenMax.from(this.$sidemenu, .3, {
              height: 0
            })
          } else {
            TweenMax.to(this.$sidemenu, .3, {
              height: 0
            })
          }
        })

        // accordion
        // add + and - elements
        this.$sidemenu.find('li.is-expanded').prepend('<div class="sidemenu-gagam"></div>')
        this.$sidemenu.find('.sidemenu-gagam').on('click', (e) => {
            $(e.target).toggleClass('active')
        })
      }
      initSearch() {
        this.$searchToggle = $('#header-search-toggle')
        this.$search = this.$searchToggle.next()
        this.$searchForm = this.$search.find('form')
        this.$searchInput = this.$search.find('input[type=text]')
        this.$searchSubmit = this.$search.find('input[type=submit]')
        this.$searchInput.detach()
        this.$searchSubmit.detach()
        this.$searchForm.insertAfter(this.$searchToggle).children().remove()
        this.$searchInput.attr('placeholder', 'Search...')
        this.$searchInput.appendTo(this.$searchForm)
        this.$searchSubmit.appendTo(this.$searchForm)
        this.$search.remove()
        this.$search = this.$searchForm.wrap('<div id="header-search-form"></div>')
        // toggle search input
        this.$searchToggle.on('click', (e) => {
          this.$searchToggle.toggleClass('active')
          if (this.$searchToggle.hasClass('active')) {
            this.$searchInput.focus()
          }
        })
        // jessica channel
        // search input has its width extended to the very right of page
        // if ($body.hasClass('section-jessica-channel')) {
        // temp
        if ($body.hasClass('section-jessica-channel')) {
          this.headerW = $('#mainmenu > .section-wrapper').width()
          $win.on('resize', this.searchResize.bind(this))
          this.searchResize()
        }
      }
      searchResize() {
        this.$searchInput.outerWidth(($doc.width() - this.headerW) / 2)
      }
    }
    new Jglobal();
  }
  if ($body.hasClass('section-jessica-tv') || $body.hasClass('section-jtv') || $body.hasClass('section-jessica-channel')) {
    class Jlanding {
      constructor() {
        this.initSocial()
        this.initSlideshow()
        this.alterLoadmore()
        // this.autoLoadmore()
      }
      initSocial() {
        this.$cover = $(`<div id="thumbnail-social-share-bar-cover"></div>`).appendTo($body)
        this.$bar = $(`
        <div id="thumbnail-social-share-bar">
            <span>分享 Share to</span>
            <a id="share-facebook"></a>
            <a id="share-mail"></a>
            <a id="share-sina"></a>
            <a id="share-close"></a>
        </div>
        `).appendTo($body)
        this.setting = 'toolbar=no, location=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=500, height=400'
        this.$facebook = this.$bar.find('#share-facebook')
        this.$mail = this.$bar.find('#share-mail')
        this.$sina = this.$bar.find('#share-sina')
        this.$close = this.$bar.find('#share-close')
        this.$facebook.on('click', (e) => {
          e.preventDefault()
          window.open('http://www.facebook.com/sharer.php?u=' + this.path + '&t=' + this.title, 'targetWindow', this.setting)
        })
        this.$sina.on('click', (e) => {
          e.preventDefault()
          window.open("http://service.weibo.com/share/share.php?url=" + this.path + "&title=" + this.title, 'targetWindow', this.setting)
        })
        this.$mail.on('click', (e) => {
          e.preventDefault()
          let mailTitle = decodeURIComponent(this.title.trim())
          let mailBody = this.path + '%0D%0A'
          // if (this.description.length > 20) {
          //   mailBody += this.description.substr(0, 20) + '...'
          // } else {
          //   mailBody += this.description
          // }
          window.location.href = `mailto:?subject=${mailTitle}&body=${mailBody}`
        })
        this.$close.on('click', (e) => {
          this.$cover.trigger('click')
        })
        this.alterThumb()
        $doc.ajaxComplete((event, xhr, settings) => {
          this.alterThumb()
        })
      }
      alterThumb() {
        $('[data-path]').each((k, v) => {
          let $v = $(v)
          if (!$v.data('inited')) {
            let path = window.location.origin + $v.attr('data-path')
            let title = $v.attr('data-title')
            let $thumbnail = $v.parent().find('.views-field-field-thumbnail')
            $thumbnail.find('img').unwrap()
            let socialHtml = `
            <div class="thumbnail-social-cover">
                <div class="thumbnail-social-links">
                    <a href="${path}" class="thumbnail-social-play">播放</a>
                    <a class="thumbnail-social-share">分享</a>
                </div>
            </div>`
            $thumbnail.append(socialHtml)
            let $share = $thumbnail.find('.thumbnail-social-share')
            $share.on('click', (e) => {
              let t = $thumbnail.offset().top + ($thumbnail.height() / 2)
              this.$bar.css({
                top: t
              })
              this.$cover.stop().fadeIn(400)
              this.$bar.stop().fadeIn(400)
              this.path = encodeURIComponent(path)
              this.title = encodeURIComponent(title)
              // $body.css('overflow', 'hidden')
              TweenLite.to(window, 1, {
                scrollTo: t - ($win.innerHeight() / 2)
              });
            })
            this.$cover.on('click', (e) => {
              this.$cover.stop().fadeOut(400)
              this.$bar.stop().fadeOut(400)
              // $body.css('overflow', 'auto')
            })
            $v.data('inited', true)
          }
        })
      }
      initSlideshow() {
        if (typeof Drupal.settings.carousel !== 'undefined') {
          this.$slideContainer = $('#slide')
          let html = `
            <div class="section-wrapper">
                <div id="slide-inner">
                    <div id="slide-sticky">
                    </div>
                    <div id="slide-wrapper">
                        <div id="slide-slick"></div>
                    </div>
                    <div id="slide-prev"></div>
                    <div id="slide-next"></div>
                </div>
            </div>`
          this.$slideContainer.append(html)
          this.$sticky = this.$slideContainer.find('#slide-sticky')
          this.$wrapper = this.$slideContainer.find('#slide-wrapper')
          this.$slick = this.$slideContainer.find('#slide-slick')
          this.$prev = this.$slideContainer.find('#slide-prev')
          this.$next = this.$slideContainer.find('#slide-next')
          _.forEach(Drupal.settings.carousel.content, (v, k) => {
            let thumbnail = v.field_thumbnail
            let rank = v.field_rank.split(' ')
            let rankNum = rank.shift()
            let rankText = rank.join(' ')
            let title = v.node_title
            let body = v.field_body
            let htmlItem = `
              <div class="slide-item">
                  <div class="slide-thumbnail">${thumbnail}</div>
                  <div class="slide-rank"><strong>${rankNum}</strong>${rankText}</div>
                  <div class="slide-title">${title}</div>
                  <p class="slide-body">${body}</p>
              </div>`
            // first 2 items are sticky
            // others are slideshow
            if (k < 2) {
              this.$sticky.append(htmlItem)
            } else {
              this.$slick.append(htmlItem)
            }
          })
          this.$slick.slick({
            prevArrow: this.$prev,
            nextArrow: this.$next,
            slidesToShow: 3,
            slidesToScroll: 3,
            // infinite: false
          })
        }
      }
      alterLoadmore() {
        this.$loadmore = $('.pager-load-more a:contains("Load more")')
        this.$loadmore.on('click', (e) => {
          this.$loadmore.text('Loading...')
        })
        $doc.ajaxComplete(() => {
          this.$loadmore.text('Load more')
        })
      }
      autoLoadmore() {
        let $loadmore = $('.pager-load-more a:contains("Load more")')
        if ($loadmore.length) {
          let buffer = 200
          $win.on('scroll', (e) => {
            if ($loadmore.offset().top <= $win.scrollTop() + $win.height() + buffer) {
              $loadmore.trigger('click')
            }
          })
          $doc.ajaxComplete(() => {
            $loadmore = $('.pager-load-more a:contains("Load more")')
            if ($loadmore.length === 0) {
              $win.off('scroll')
            }
          })
        }
      }
    }
    new Jlanding()
  }
})
